<template>
  <div class="knowledge-base-container">
    <div class="page-header">
      <el-page-header
        title="我的知识库"
        content="管理您的知识库"
        @back="goBack"
        style="width: 100%;"
      >
      </el-page-header>
        <el-button type="primary" icon="el-icon-plus" @click="createKnowledgeBase">创建知识库</el-button>
    </div>

    <el-table :data="knowledgeBaseList" style="width: 100%" v-loading="tableLoading">
      <el-table-column prop="name" label="知识库名称"></el-table-column>
      <el-table-column prop="docCount" label="文档数量" width="140">
        <template slot-scope="scope">
          {{ scope.row.docCount !== null ? scope.row.docCount : '加载中...' }}
        </template>
      </el-table-column>
      <el-table-column prop="lastModified" label="最后更新时间" width="200">
        <template slot-scope="scope">
          {{ scope.row.lastModified || '--' }}
        </template>
      </el-table-column>
      <el-table-column label="操作" width="280">
        <template slot-scope="scope">
          <el-button size="mini" @click="viewKnowledgeBase(scope.row)">查看</el-button>
          <el-button size="mini" @click="editKnowledgeBase(scope.row)">加入文档</el-button>
          <el-button size="mini" type="danger" @click="deleteKnowledgeBase(scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="pagination-wrapper" v-if="pagination.total > 0">
      <el-pagination
        background
        layout="prev, pager, next, jumper, ->, total"
        :total="pagination.total"
        :current-page.sync="pagination.pageNum"
        :page-size="pagination.pageSize"
        @current-change="handleTablePageChange"
      />
    </div>

    <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="60%">
      <el-form :model="currentKnowledgeBase" :rules="rules" ref="knowledgeBaseForm" label-width="100px">
        <el-form-item label="知识库名称" prop="name">
          <el-input
            v-model="currentKnowledgeBase.name"
            :disabled="dialogTitle === '加入文档'"
            placeholder="请输入知识库名称"
          ></el-input>
        </el-form-item>

        <template v-if="dialogTitle === '加入文档'">
          <el-form-item v-if="documentList.length === 0" label="文本内容">
            <el-input
              type="textarea"
              :rows="5"
              v-model="manualText"
              placeholder="输入要加入的文本内容"
              @input="handleManualTextInput"
            ></el-input>
            <div class="input-tip">
              <span v-if="!hasManualText">可直接输入文本或上传文档生成分片</span>
              <span v-else>已填写文本，若需上传文件请先清空文本内容</span>
            </div>
          </el-form-item>

          <el-form-item
            label="上传文档"
            v-if="documentList.length === 0 && !hasManualText"
          >
            <el-upload
              class="upload-demo"
              :auto-upload="false"
              :on-change="handleFileChange"
              :on-remove="handleRemove"
              :before-remove="beforeRemove"
              multiple
              :limit="10"
              :on-exceed="handleExceed"
              :file-list="fileList"
            >
              <el-button size="small" type="primary">点击上传</el-button>
              <div slot="tip" class="el-upload__tip">支持 PDF/DOC/DOCX/TXT 文件，上传后会自动解析为文档分片</div>
            </el-upload>
          </el-form-item>

          <el-form-item v-if="documentList.length > 0" label="文档分片列表">
            <el-table :data="documentList" style="width: 100%" max-height="320" border>
              <el-table-column type="index" label="序号" width="60"></el-table-column>
              <el-table-column prop="id" label="分片ID" width="180"></el-table-column>
              <el-table-column label="内容预览" show-overflow-tooltip>
                <template slot-scope="scope">
                  {{ previewDocument(scope.row) }}
                </template>
              </el-table-column>
              <el-table-column prop="metadata" label="来源" width="150">
                <template slot-scope="scope">
                  <el-tag size="mini" v-if="scope.row.metadata && scope.row.metadata.source">
                    {{ scope.row.metadata.source }}
                  </el-tag>
                </template>
              </el-table-column>
            </el-table>
            <div class="doc-list-actions">
              <el-button size="small" @click="clearDocumentList">清空列表</el-button>
              <span class="doc-count">共 {{ documentList.length }} 个文档分片</span>
            </div>
          </el-form-item>
        </template>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button
          v-if="dialogTitle === '创建知识库'"
          type="primary"
          :loading="loading"
          @click="saveKnowledgeBase"
        >确 定</el-button>
        <el-button
          v-if="dialogTitle === '加入文档'"
          type="primary"
          :disabled="!hasManualText && documentList.length === 0"
          :loading="loading"
          @click="submitKnowledgeBaseContent"
        >保 存</el-button>
      </div>
    </el-dialog>

    <el-dialog title="查看知识库" :visible.sync="viewDialogVisible" width="60%">
      <el-form :model="viewOnlyKnowledgeBase" label-width="100px" disabled>
        <el-form-item label="知识库名称">
          <el-input v-model="viewOnlyKnowledgeBase.name"></el-input>
        </el-form-item>
      </el-form>
      <el-table :data="viewOnlyKnowledgeBase.chunks" style="width: 100%" max-height="400" v-loading="viewLoading">
        <el-table-column prop="id" label="分片ID" width="180"></el-table-column>
        <el-table-column prop="preview" label="内容预览"></el-table-column>
        <el-table-column label="操作" width="180">
          <template slot-scope="scope">
            <el-button size="mini" @click="editChunk(scope.row, scope.$index)">编辑</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div slot="footer" class="dialog-footer">
        <el-button @click="viewDialogVisible = false">关 闭</el-button>
      </div>
    </el-dialog>

    <el-dialog title="编辑分片内容" :visible.sync="editChunkDialogVisible" width="50%">
      <el-input type="textarea" :rows="10" v-model="editingChunk.content"></el-input>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editChunkDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveChunk">保 存</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  getVectorList,
  createVector,
  deleteVector,
  uploadVectorFile,
  createVectorShards,
  getVectorShards
} from '@/api/api';

export default {
  name: 'KnowledgeBase',
  data() {
    return {
      loading: false,
      tableLoading: false,
      knowledgeBaseList: [],
      pagination: {
        pageNum: 1,
        pageSize: 10,
        total: 0,
      },
      dialogVisible: false,
      dialogTitle: '',
      currentKnowledgeBase: { id: null, name: '' },
      fileList: [],
      documentList: [],
      manualText: '',
      viewDialogVisible: false,
      viewOnlyKnowledgeBase: { id: null, name: '', chunks: [] },
      viewLoading: false,
      editChunkDialogVisible: false,
      editingChunk: { id: null, content: '' },
      editingChunkIndex: null,
      rules: {
        name: [
          { required: true, message: '请输入知识库名称', trigger: 'blur' }
        ]
      }
    };
  },
  computed: {
    hasManualText() {
      return !!(this.manualText && this.manualText.trim().length > 0);
    }
  },
  created() {
    this.fetchKnowledgeBases();
  },
  methods: {
    goBack() {
      this.$router.push({ name: 'AI应用平台' });
    },
    async fetchKnowledgeBases() {
      this.tableLoading = true;
      try {
        const response = await getVectorList({
          pageNum: this.pagination.pageNum,
          pageSize: this.pagination.pageSize
        });
        if (response.data && response.data.message === '成功') {
          const pageInfo = response.data.data || {};
          const list = pageInfo.list || [];
          this.pagination.total = pageInfo.total || 0;
          this.pagination.pageNum = pageInfo.pageNum || this.pagination.pageNum;
          this.pagination.pageSize = pageInfo.pageSize || this.pagination.pageSize;
          this.knowledgeBaseList = list.map(item => ({
            id: item.id,
            name: item.vectext,
            docCount: null,
            lastModified: '--'
          }));
          if (this.knowledgeBaseList.length === 0 && this.pagination.total > 0 && this.pagination.pageNum > 1) {
            this.pagination.pageNum = Math.max(1, this.pagination.pageNum - 1);
            await this.fetchKnowledgeBases();
            return;
          }
          await Promise.all(this.knowledgeBaseList.map(kb => this.loadDocCount(kb)));
        } else {
          this.knowledgeBaseList = [];
          this.$message.error(response.data?.message || '获取知识库失败');
        }
      } catch (error) {
        console.error('获取知识库失败', error);
        this.$message.error('获取知识库失败');
      } finally {
        this.tableLoading = false;
      }
    },
    handleTablePageChange(page) {
      this.pagination.pageNum = page;
      this.fetchKnowledgeBases();
    },
    async loadDocCount(kb) {
      try {
        const res = await getVectorShards(kb.id);
        if (res.data && res.data.message === '成功') {
          const shards = res.data.data || [];
          kb.docCount = shards.length;
        } else {
          kb.docCount = 0;
        }
      } catch (error) {
        kb.docCount = 0;
      }
    },
    createKnowledgeBase() {
      this.dialogTitle = '创建知识库';
      this.currentKnowledgeBase = { id: null, name: '' };
      this.fileList = [];
      this.documentList = [];
      this.manualText = '';
      this.dialogVisible = true;
      this.$nextTick(() => {
        if (this.$refs.knowledgeBaseForm) {
          this.$refs.knowledgeBaseForm.clearValidate();
        }
      });
    },
    editKnowledgeBase(kb) {
      this.dialogTitle = '加入文档';
      this.currentKnowledgeBase = { ...kb };
      this.fileList = [];
      this.documentList = [];
      this.manualText = '';
      this.dialogVisible = true;
    },
    async saveKnowledgeBase() {
      if (!this.$refs.knowledgeBaseForm) return;
      const valid = await new Promise(resolve => {
        this.$refs.knowledgeBaseForm.validate(result => resolve(result));
      });
      if (!valid) {
        this.$message.error('请输入知识库名称');
        return;
      }
      this.loading = true;
      try {
        const response = await createVector(this.currentKnowledgeBase.name.trim());
        if (response.data && response.data.message === '成功') {
          this.$message.success('创建成功');
          this.dialogVisible = false;
          await this.fetchKnowledgeBases();
        } else {
          this.$message.error(response.data?.message || '创建失败');
        }
      } catch (error) {
        console.error('创建知识库失败', error);
        this.$message.error('创建知识库失败');
      } finally {
        this.loading = false;
      }
    },
    async deleteKnowledgeBase(kb) {
      this.$confirm(`确定要删除知识库 "${kb.name}" 吗?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }).then(async () => {
        try {
          const response = await deleteVector(kb.id);
          if (response.data && response.data.message === '成功') {
            this.$message.success('删除成功!');
            await this.fetchKnowledgeBases();
          } else {
            this.$message.error(response.data?.message || '删除失败');
          }
        } catch (error) {
          console.error('删除知识库失败', error);
          this.$message.error('删除失败');
        }
      }).catch(() => {
        this.$message.info('已取消删除');
      });
    },
    async viewKnowledgeBase(kb) {
      this.viewOnlyKnowledgeBase = { id: kb.id, name: kb.name, chunks: [] };
      this.viewDialogVisible = true;
      this.viewLoading = true;
      try {
        const response = await getVectorShards(kb.id);
        if (response.data && response.data.message === '成功') {
          const list = response.data.data || [];
          this.viewOnlyKnowledgeBase.chunks = list.map(item => ({
            id: item.id,
            content: item.text,
            preview: item.text && item.text.length > 100 ? `${item.text.slice(0, 100)}...` : item.text
          }));
        } else {
          this.viewOnlyKnowledgeBase.chunks = [];
        }
      } catch (error) {
        console.error('获取文档分片失败', error);
        this.$message.error('获取文档分片失败');
        this.viewOnlyKnowledgeBase.chunks = [];
      } finally {
        this.viewLoading = false;
      }
    },
    editChunk(chunk, index) {
      this.editingChunk = { ...chunk };
      this.editingChunkIndex = index;
      this.editChunkDialogVisible = true;
    },
    saveChunk() {
      if (this.editingChunkIndex !== null) {
        this.$set(this.viewOnlyKnowledgeBase.chunks, this.editingChunkIndex, {
          ...this.editingChunk,
          preview: this.editingChunk.content && this.editingChunk.content.length > 100
            ? `${this.editingChunk.content.slice(0, 100)}...`
            : this.editingChunk.content
        });
      }
      this.editChunkDialogVisible = false;
      this.$message.success('分片内容已更新 (模拟保存)');
    },
    async handleFileChange(file, fileList) {
      this.fileList = fileList;
      const fileName = file.name;
      const fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1).toLowerCase();
      if (!['pdf', 'doc', 'docx', 'txt'].includes(fileExtension)) {
        this.$message.warning('不支持的文件类型，仅支持 PDF/DOC/DOCX/TXT 文件');
        return;
      }
      if (!this.currentKnowledgeBase.id) {
        this.$message.warning('请先选择知识库');
        return;
      }
      try {
        this.loading = true;
        const response = await uploadVectorFile(this.currentKnowledgeBase.id, file.raw || file);
        const docs = Array.isArray(response.data) ? response.data : [];
        if (docs.length === 0) {
          this.$message.warning('未从文件中解析出有效内容');
          return;
        }
        const formatted = docs
          .map((doc, index) => {
            const content = doc.content || doc.text || '';
            if (!content) return null;
            return {
              id: doc.id || `doc-${Date.now()}-${index}`,
              content,
              metadata: doc.metadata || {},
              sourceFile: file.name
            };
          })
          .filter(Boolean);
        this.documentList = [...this.documentList, ...formatted];
        this.manualText = '';
        if (file) {
          file.status = 'success';
        }
        this.$message.success(`文件 "${file.name}" 解析成功，生成 ${formatted.length} 个文档分片`);
      } catch (error) {
        console.error('文件解析失败', error);
        this.$message.error('文件解析失败');
      } finally {
        this.loading = false;
      }
    },
    clearDocumentList() {
      this.documentList = [];
      this.fileList = [];
      this.manualText = '';
      this.$message.info('已清空文档列表');
    },
    handleManualTextInput() {
      if (this.manualText && this.manualText.trim().length > 0) {
        this.fileList = [];
        this.documentList = [];
      }
    },
    async submitKnowledgeBaseContent() {
      if (!this.currentKnowledgeBase.id) {
        this.$message.error('请选择要加入的知识库');
        return;
      }
      let payload = [];
      if (this.documentList.length > 0) {
        payload = this.documentList.map(doc => ({
          id: doc.id,
          text: doc.content || doc.text || '',
          metadata: doc.metadata || {}
        }));
      } else if (this.hasManualText) {
        const trimmed = this.manualText.trim();
        payload = [{
          id: `manual-doc-${Date.now()}`,
          text: trimmed,
          metadata: {
            source: '手动输入'
          }
        }];
      } else {
        this.$message.warning('请先输入文本或上传文档');
        return;
      }
      this.loading = true;
      try {
        const response = await createVectorShards(this.currentKnowledgeBase.id, payload);
        if (response.data && response.data.message === '成功') {
          this.$message.success('文档上传成功');
          this.dialogVisible = false;
          this.documentList = [];
          this.fileList = [];
          this.manualText = '';
          await this.fetchKnowledgeBases();
        } else {
          this.$message.error(response.data?.message || '上传失败');
        }
      } catch (error) {
        console.error('上传文档失败', error);
        this.$message.error('上传失败');
      } finally {
        this.loading = false;
      }
    },
    handleRemove(file, fileList) {
      this.fileList = fileList;
      this.documentList = this.documentList.filter(doc => doc.sourceFile !== file.name);
    },
    handlePreview(file) {
      if (file.url) {
        window.open(file.url);
      }
    },
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 10 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`);
    },
    beforeRemove(file) {
      return this.$confirm(`确定移除 ${ file.name }？移除后对应的文档分片也会被清除。`);
    },
    previewDocument(doc) {
      const content = doc.content || doc.text || '';
      if (!content) return '';
      return content.length > 100 ? `${content.substring(0, 100)}...` : content;
    }
  },
};
</script>

<style scoped>
.knowledge-base-container {
  padding: 24px;
  background-color: #f5f7fa;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 24px;
  padding-bottom: 16px;
  border-bottom: 1px solid #dcdfe6;
}

.page-header h1 {
  font-size: 24px;
  color: #303133;
}

.el-table {
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
}

.upload-demo {
  width: 100%;
}

.el-dialog__body {
  padding: 20px 20px 0 20px;
}

.el-dialog__footer {
  padding-top: 0;
}

.input-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
}

.doc-list-actions {
  margin-top: 10px;
  display: flex;
  align-items: center;
}

.doc-count {
  margin-left: 10px;
  color: #909399;
}

.pagination-wrapper {
  display: flex;
  justify-content: flex-end;
  margin-top: 16px;
}
</style>

